<template>
  <CustomDialog ref="customDialog" width="1000px" :title="dialogProps.title" :isView="dialogProps.isView"
    :onSubmit="handleSubmit" :onClose="handleClose" class="role-dialog">
    <template #header>
      {{ `${dialogProps.title}角色` }}
    </template>
    <template #content>

      <el-form ref="ruleFormRef" :model="dialogProps.row" :rules="rules" class="form-box">
        <el-form-item label="角色名称：" prop="roleName">
          <BInput v-model="dialogProps.row!.roleName" placeholder="请填写角色名称" clearable />
        </el-form-item>
        <div>
          <el-row :gutter="16" style="height: 2rem;">
            <el-col :span="8">
              <div class="tree-operation">
                <div class="tree-checked-all"><el-checkbox v-model="checked1" label="全选"
                    @change="handleCheckedAllChange" /></div>
                <div class="tree-checked-all"><el-checkbox v-model="checked2" label="全部展开"
                    @change="handleExpendAllChange" /></div>
              </div>
            </el-col>
            <el-col :span="12" :offset="4">
              <el-form>
                <el-form-item label="数据权限:">
                  <el-select v-model="dialogProps.row.dataScope" placeholder="请选择数据权限" clearable
                    @change="handleDataPermissions">
                    <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
                  </el-select>
                </el-form-item>
              </el-form>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <CustomTree ref="treeRef" :treeData="treeFilterData" :checkedKeys="checkedKeys" :avaChecked="true"
                :alleExpanded="alleExpanded" :allChecked="allChecked" @node-checked="handleNodeChecked"
                @node-click="handleNodeClick" :dataScopeValue="dataScopeValue">
                <template v-slot:treeOperation="{ node }">
                  <el-form v-if="node" :model="node">
                    <el-row :gutter="20">
                      <el-col :span="12">
                        <el-form-item>
                          <el-select v-model="node.dataScope" placeholder="请选择数据权限" clearable>
                            <el-option v-for="item in options" :key="item.value" :label="item.label"
                              :value="item.value" />
                          </el-select>
                        </el-form-item>
                      </el-col>
                      <el-col :span="12" v-if="node.dataScope === 4">
                        <el-form-item>
                          <el-tree-select v-model="node.deptIds" :data="organizeData" multiple
                            :render-after-expand="false" show-checkbox check-strictly check-on-click-node
                            placeholder="请选择部门" :default-checked-keys="chckedDeptKeys" clearable filterable
                            @check="(data: any, treeNode: any) => handleSelectDept(data, treeNode, node)" />
                        </el-form-item>
                      </el-col>
                    </el-row>
                  </el-form>
                </template>
              </CustomTree>
            </el-col>
          </el-row>
        </div>
      </el-form>
    </template>
    <template #footer>
      <el-button @click="customDialog?.acceptParams(false)">取消</el-button>
      <el-button v-show="!dialogProps.isView" type="primary" @click="handleSubmit">确定</el-button>
    </template>
  </CustomDialog>
</template>

<script setup lang="ts">
import { ref, reactive, watch } from "vue";
import { ElMessage, ElTree, FormInstance, selectKey } from "element-plus";
import CustomDialog from "@/components/Dialog/CustomDialog.vue";
import BInput from "@/components/BaseComponents/BInput.vue";
import SButton from "@/components/SButton/index.vue";
import { getMenuList, getOrgTreeList, getRoleDetail } from "@/api/basic/role";
import CustomTree from '@/components/CustomTree/index.vue'

const rules = reactive({
  roleName: [{ required: true, message: "请填写角色名称" }]
});

interface DialogProps {
  title: string;
  isView: boolean;
  row: any;
  api?: (params: any) => Promise<any>;
  getTableList?: () => void;
}

const dialogProps = ref<DialogProps>({
  isView: false,
  title: "",
  row: {
    id: '',
    roleName: '',
    dataScope: '',
    menuIds: [],
    deptIds: []
  },
});

const checked1 = ref(false)
const checked2 = ref(false)
const options = ref([
  {
    value: 1,
    label: '本人'
  },
  {
    value: 2,
    label: '本部门权限'
  },
  {
    value: 3,
    label: '本部门及以下数据权限'
  },
  {
    value: 4,
    label: '自定义权限'
  },
  {
    value: 5,
    label: '全部'
  }
])

//获取菜单列表
const treeFilterData = ref<any>()
const menuList = ref<any>()
const obtainTheMenuList = async () => {
  const res = await getMenuList();
  treeFilterData.value = convertToTreeData(res);
  menuList.value = res
};
obtainTheMenuList()

const customDialog = ref<InstanceType<typeof CustomDialog>>();
// 接收父组件传过来的参数
const acceptParams = async (params: DialogProps) => {
  //修改，使新增时数据不清除
  dialogProps.value.api = params.api;
  dialogProps.value.getTableList = params.getTableList;
  dialogProps.value.title = params.title;
  dialogProps.value.isView = params.isView;

  if (JSON.stringify(params.row) !== '{}' || params.title === '编辑') {
    //获取详情
    dialogProps.value.row = await getRoleDetail(params.row.id)
  }
  customDialog.value?.acceptParams(true);
};


const checkedKeys = ref<any[]>([]);  //选中复选框的树节点
const chckedDeptKeys = ref<any[]>([])
watch(
  () => dialogProps.value.row,
  (newValue) => {
    if (newValue.menuList && newValue.menuList.length > 0) {
      treeFilterData.value = convertToTreeData(newValue.menuList);
      const extractCheckedKeys = (menuItems: MenuItem[]): any[] => {
        return menuItems.reduce<any[]>((acc, item) => {
          if (item.select) {
            acc.push(item.id);
          }
          if (item.listChildMenu) {
            acc.push(...extractCheckedKeys(item.listChildMenu));
          }
          return acc;
        }, []);
      };

      checkedKeys.value = extractCheckedKeys(newValue.menuList);
    }
  }, { immediate: true }
);
const organizeData = ref<any>([])

interface TreeSelectNode {
  id: number;
  value: any,
  label: string;
  children: TreeSelectNode[];
}

function convertToTreeSelectData(nodes: any[]): TreeSelectNode[] {
  return nodes.map(node => {
    const treeSelectNode: TreeSelectNode = {
      id: node.id,
      value: node.id,
      label: node.deptName,
      children: []
    };

    if (node.children) {
      treeSelectNode.children = convertToTreeSelectData(node.children);
    }

    return treeSelectNode;
  });
}

const getOrganizationTree = () => {
  getOrgTreeList().then(res => {
    if (res) {
      organizeData.value = convertToTreeSelectData(res)
    }
  })
}
getOrganizationTree()

const filterMethod = (value: string, data: any) => {
  console.log(value, data);
}
const handleSelectDept = (data: any, treeNode: any, node: any) => {
  const idsSet = new Set(node.deptIds || []);

  if (data.id) {
    idsSet.add(data.id);
  }

  // 将 Set 转换为数组并赋值给 node.deptIds
  node.deptIds = Array.from(idsSet);
}

const treeRef = ref<any>(null);
// 树形数据转成需要的数据
interface MenuItem {
  id: number;
  menuName: string;
  dataPermission: string,
  parentId: number;
  url: string;
  menuType: string;
  perms: string;
  orderNum: string | null;
  visible: string;
  dataScope: string | null;
  deptIds: string | null;
  select: string | null;
  listChildMenu?: MenuItem[];
}

interface TreeNode {
  id: number;
  menuName: string;
  menuType: string;
  dataPermission: string,
  expanded: boolean;
  select: boolean;
  disabled: boolean;
  indeterminate: boolean;
  parentId: number;
  dataScope: string | null;
  deptIds: any;
  isLast: boolean;
  listChildMenu: TreeNode[];
  isLastLayer: boolean;
}

const convertToTreeData = (menuItems: MenuItem[]): TreeNode[] => {
  const setLastNodeFlag = (nodes: TreeNode[]) => {
    if (nodes.length > 0) {
      nodes[nodes.length - 1].isLast = true;
    }
  };

  const convertNode = (menuItem: MenuItem): TreeNode => {
    const node: TreeNode = {
      id: menuItem.id,
      menuName: menuItem.menuName,
      menuType: menuItem.menuType,
      dataPermission: menuItem.dataPermission,
      expanded: false,
      select: false,
      disabled: false,
      indeterminate: false,
      parentId: menuItem.parentId,
      dataScope: menuItem.dataScope,
      deptIds: menuItem.deptIds,
      isLast: false,
      listChildMenu: [],
      isLastLayer: false
    };

    if (menuItem.listChildMenu) {
      node.listChildMenu = menuItem.listChildMenu.map(convertNode);
    }

    if (menuItem.menuType === 'C' && menuItem.listChildMenu && menuItem.listChildMenu.length > 0) {
      const buttonNodes = menuItem.listChildMenu.filter(item => item.menuType === 'B').map(convertNode);
      node.listChildMenu?.push(...buttonNodes);
      if (node.listChildMenu) {
        setLastNodeFlag(node.listChildMenu);
        node.listChildMenu.forEach(buttonNode => {
          buttonNode.isLastLayer = true;
        });
      }
    }

    return node;
  };

  const treeData: TreeNode[] = menuItems.map(convertNode);
  setLastNodeFlag(treeData);


  return treeData;
};

//选中
const handleNodeChecked = (node: any) => {

}

//点击
const handleNodeClick = (node: any) => {

}

//全选
const allChecked = ref(true)
const handleCheckedAllChange = (val: boolean) => {
  allChecked.value = val
  if (val && treeRef.value) {
    treeRef.value?.selectAll()
  } else if (!val && treeRef.value) {
    treeRef.value?.unSelectAll()
  }
}

//展开/缩回
const alleExpanded = ref(true)
const handleExpendAllChange = (val: boolean) => {

  alleExpanded.value = val
  if (val && treeRef.value) {
    treeRef.value?.expandAll()
  } else if (!val && treeRef.value) {
    treeRef.value?.collapseAll()
  }
}

//数据权限
const dataScopeValue = ref<any>()
const handleDataPermissions = (val: any) => {
  dataScopeValue.value = val
  const setDataScops = (nodes: any[]) => {
    nodes.forEach(node => {
      node.dataScope = val
      if (node.listChildMenu) {
        setDataScops(node.listChildMenu)
      }
    })
  }

  if (treeFilterData.value) {
    setDataScops(treeFilterData.value)
  }
}

function setDataScope(menuList: any) {
  menuList.forEach(item => {
    if (item.dataPermission === 0) {
      item.dataScope = null;
    } else if (item.dataPermission === 1) {
      // 保持 dataScope 不变
      item.dataScope = item.dataScope
    }

    // 递归处理子菜单
    if (item.listChildMenu && item.listChildMenu.length > 0) {
      setDataScope(item.listChildMenu);
    }
  });
}
// 提交数据（新增/编辑）
const ruleFormRef = ref<FormInstance>();
const handleSubmit = async () => {
  ruleFormRef.value!.validate(async valid => {
    if (!valid) return;
    try {
      // 调用方法
      setDataScope(treeFilterData.value);
      dialogProps.value.row.menuList = treeFilterData.value

      await dialogProps.value.api!(dialogProps.value.row);
      ElMessage.success({ message: `${dialogProps.value.title}角色成功！` });
      dialogProps.value.getTableList!();
      customDialog.value?.acceptParams(false);
      ruleFormRef.value?.resetFields();
      checked1.value = false
      checked2.value = false
      dialogProps.value.row = {}

    } catch (error) {
      console.log(error);
    }
  });
};

const handleClose = () => {
  customDialog.value?.acceptParams(false);
  checkedKeys.value = []
  dialogProps.value.row = {}
  checked1.value = false
  checked2.value = false
  // obtainTheMenuList()
};

defineExpose({
  acceptParams
});

</script>

<style lang="scss" scoped>
//设置对话框的高度不变
:deep(.el-tabs__content) {
  height: 430px;
}

//设置tabs
.steps-tabs {
  :deep(.el-tabs__nav-wrap:after) {
    background-color: unset;
  }

  :deep(.el-tabs__nav) {
    float: none;
    display: flex;
    justify-content: center;
  }
}

//表单
.form-box {
  width: 60%;
  margin: 0 auto;
}

.tree-table-box {
  display: flex;
  justify-content: space-around;

  .left-tree-box {
    width: 20%;
    height: 430px;
    overflow: hidden;

    //设置滚动
    .left-checkbox {
      width: 100%;
      max-height: 400px;
      overflow-y: auto;
    }
  }

  .left-table-box {
    width: 78%;
    margin-left: 2%;
    max-height: 400px;
    overflow-y: auto;

    .header-box {
      width: 100%;
      display: flex;
      flex-direction: column;
      align-items: center;

      .header-title {
        width: 100%;
        text-align: center;
        font-size: 1rem;
        background-color: #f2f2f2;
        padding: 1rem 0;
        box-sizing: border-box
      }

      .checkbox-box {
        width: 100%;
        margin: 0.5rem 0;
        display: flex;
        align-items: center;

        justify-content: flex-start;

        div {
          margin-right: 0.5rem;
        }
      }
    }

    :deep(.table-main) {
      width: 100%;
      height: auto;
    }
  }
}

.tree-operation {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
</style>
